package sims.library;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.cfg.AnnotationConfiguration;
import java.util.List;

public abstract class ControllerCore {

    protected Session session;
    protected Criteria crit;
    protected Query query;

    public ControllerCore() {
        try {
            session = null;
            session = new AnnotationConfiguration().configure().buildSessionFactory().openSession();
        } catch (Throwable e) {
            System.err.println("Can not create session factory");
            throw new ExceptionInInitializerError(e);
        }
    }

    protected void beginTransaction() {
        this.session.beginTransaction();
    }

    protected void commitAndClose() {
        if (session != null) {
            session.getTransaction().commit();

//            if (session.isOpen()) {
//                session.close();
//            }

        }
    }

    protected void insertCore(Object object) {
        try {
            beginTransaction();
            this.session.save(object);
            commitAndClose();
        } catch (Exception e) {
            e.printStackTrace();
            if(session!=null){
                session.beginTransaction().rollback();
            }
        }
    }

    protected void updateCore(Object object) {
        beginTransaction();
        this.session.merge(object);
        commitAndClose();
    }

    protected void deleteCore(Object object) {
        beginTransaction();
        this.session.delete(object);
        commitAndClose();
    }

    protected List getAllCore(Class type) {
        createCriteria(type);
        return this.crit.list();
    }

    protected List getAllCore(String hql) {
        beginTransaction();
        createQuery(hql);
        commitAndClose();
        return this.query.list();
    }

    protected List pagingCore(String hql, int first, int max) {
        beginTransaction();
        this.query = session.createQuery(hql);
        query.setFirstResult(first);
        query.setMaxResults(max);
        commitAndClose();
        return query.list();
    }

    protected List pagingCore(Class type, int first, int max) {
        createCriteria(type);
        crit.setFirstResult(first);
        crit.setMaxResults(max);
        return crit.list();
    }

    protected Object getByIdCore(Class type, int id) {
        beginTransaction();
        return (Object) session.load(type, id);
    }

//	protected abstract Object returnObject(int id);
    protected int countPageCore(String hql, int maxResults) {
        beginTransaction();
        this.query = session.createQuery(hql);
        commitAndClose();
        List l = this.query.list();
        int totalResults = l.size();
        int totalPages = totalResults / maxResults;
        if ((totalResults % maxResults) != 0) {
            totalPages++;
        }
        return totalPages;
    }

    protected int countPageCore(Class type, int maxResults) {
        createCriteria(type);
        int totalResults = ((Long) crit.list().get(0)).intValue();
        int totalPages = totalResults / maxResults;
        if ((totalResults % maxResults) != 0) {
            totalPages++;
        }
        return totalPages;
    }

    protected void createCriteria(Class type) {
        beginTransaction();
        crit = session.createCriteria(type);
        commitAndClose();
    }

    protected void createQuery(String hql) {
        query = session.createQuery(hql);
    }

    protected int executeUpdateCore(String hql) {
        beginTransaction();
        createQuery(hql);
        return this.query.executeUpdate();
    }

    public abstract void insert(Object obj);

    public abstract void update(Object obj);

    public abstract void delete(Object obj);

    public abstract List getAll(Class type);

    public abstract List getAll(String hql);

    public abstract Object getById(Class type, int id);

    public abstract int countPage(String hql, int maxresults);

    public abstract int countPage(Class type, int maxresults);

    public abstract int executeUpdate(String hql);

    public abstract List paging(String hql, int first, int max);

    public abstract List paging(Class type, int first, int max);
}
